package com.yunhe.marketing.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.mybatis.PageResult;
import com.yunhe.common.util.StringUtil;
import com.yunhe.es.util.QueryBuilderUtil;
import com.yunhe.marketing.constant.EnterpriseConsts;
import com.yunhe.marketing.domain.Enterprise;
import com.yunhe.marketing.domain.FilterCondition;
import com.yunhe.marketing.esdomain.EsDataClueDemand;
import com.yunhe.marketing.esrepository.EsDataClueDemandrepository;
import com.yunhe.marketing.model.ClueFilterCondition;
import com.yunhe.marketing.model.ClueQueryCondition;
import com.yunhe.marketing.repository.EnterpriseRepository;
import com.yunhe.marketing.repository.FilterConditionRepository;
import com.yunhe.marketing.service.IClueRepositoryService;
import com.yunhe.marketing.util.BeansUtil;
import com.yunhe.marketing.util.EnterpriseUtil;
import com.yunhe.common.util.CollectionUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: ClueRepositoryServiceImpl
 * @Description:
 * @author: GongDaCheng
 * @Date: 10:13 2021/2/24
 */
@Service
public class ClueRepositoryServiceImpl implements IClueRepositoryService {

    private static final Logger log = LoggerFactory.getLogger(ClueRepositoryServiceImpl.class);
    @Autowired
    EnterpriseRepository enterpriseRepository;

    @Autowired
    FilterConditionRepository filterConditionRepository;
    @Autowired
    EsDataClueDemandrepository esDataClueDemandrepository;


    private final static String infinite = "infinite";

    @Override
    public PageResult selectClueByClueQueryCondition(ClueFilterCondition clueFilterCondition , int page , int size) throws ParseException {
        /**
         * ClueFilterCondition转换为ClueQueryCondition
         * ClueFilterCondition区间为一个字段，起始值（下界）终止值（上界）用“，”隔开，如：500,1000
         * ClueQueryCondition区间为两个字段，xxxStart：500，xxxEnd：1000
         * 当ClueFilterCondition无终止值（上界）时（即筛选条件为大于等于某一值），终止值（上界）用infinite表示，如：500，infinite;此时ClueQueryCondition中xxxEnd的值为null
         * */
        ClueQueryCondition clueQueryCondition = new ClueQueryCondition();
        BeanUtils.copyProperties(clueFilterCondition,clueQueryCondition);
        clueQueryCondition.setEnterpriseScaleSection(clueFilterCondition.getEnterpriseScale());
        clueQueryCondition.setRegisteredCapitalSection(clueFilterCondition.getRegisteredCapital());
        clueQueryCondition.setNumberOfInsuredSection(clueFilterCondition.getNumberOfInsured());
        String filterPaidInCapital = clueFilterCondition.getPaidInCapital();
        String filterEstablishDate = clueFilterCondition.getEstablishDate();
        String filterAnnualTurnover = clueFilterCondition.getAnnualTurnover();

        if (filterPaidInCapital != null){
            String[] paidInCapital = filterPaidInCapital.split(",");
            if (paidInCapital.length == 2) {
                if(!StringUtil.isEmpty(paidInCapital[0])){
                    clueQueryCondition.setPaidInCapitalStart(Double.valueOf(paidInCapital[0]));
                }
                if (infinite.equals(paidInCapital[1])) {
                    clueQueryCondition.setPaidInCapitalEnd(null);
                } else {
                    clueQueryCondition.setPaidInCapitalEnd(Double.valueOf(paidInCapital[1]));
                }
            }
        }
        if (filterAnnualTurnover != null){
            String[] annualTurnover = filterAnnualTurnover.split(",");
            if (annualTurnover.length == 2) {
                if(!StringUtil.isEmpty(annualTurnover[0])){
                    clueQueryCondition.setAnnualTurnoverStart(Double.valueOf(annualTurnover[0]));
                }
                if (infinite.equals(annualTurnover[1])) {
                    clueQueryCondition.setAnnualTurnoverEnd(null);
                } else {
                    clueQueryCondition.setAnnualTurnoverEnd(Double.valueOf(annualTurnover[1]));
                }
            }
        }
        if (filterEstablishDate != null){
            String[] establishDate = filterEstablishDate.split(",");
            if (establishDate.length == 2) {
                if(!StringUtil.isEmpty(establishDate[0])){
                    clueQueryCondition.setEstablishDateStart(establishDate[0]);
                }
                clueQueryCondition.setEstablishDateStart(establishDate[0]);
                String establishDateEndStr = establishDate[1];
                if (infinite.equals(establishDateEndStr)) {
                    clueQueryCondition.setEstablishDateEnd(null);
                } else {
                    clueQueryCondition.setEstablishDateEnd(establishDateEndStr);
                }
            }
        }
        PageResult result = null;
        Pageable pageable = PageRequest.of(page -1 , size);
        //查询对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("informationType","1"));
        QueryBuilder queryBuilder = QueryBuilderUtil.getQueryBuilder(clueQueryCondition, boolQueryBuilder);
        //构建查询
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withSort(SortBuilders.fieldSort("allocationStatus.keyword").order(SortOrder.ASC).unmappedType("string"))
                .withSort(SortBuilders.fieldSort("operationStatus.keyword").order(SortOrder.ASC).unmappedType("string"))
                .withSort(SortBuilders.fieldSort("establishDateSort.keyword").order(SortOrder.ASC).unmappedType("long"))
                .withSort(SortBuilders.fieldSort("enterpriseNameInitials.keyword").order(SortOrder.ASC).unmappedType("string"))
                //.addAggregation(builder)
                .withPageable(pageable)
                .build();
        Page<EsDataClueDemand> esDataClueDemandPage = esDataClueDemandrepository.search(query);
        List<EsDataClueDemand> content = esDataClueDemandPage.getContent();
        List<Enterprise> enterpriseList = BeansUtil.listCopy(content, Enterprise.class);
        return new PageResult(page ,size, (int) esDataClueDemandPage.getTotalElements(),enterpriseList);
    }


    @Override
    public FilterCondition saveClueFilterCondition(Long userId , String conditionName , ClueFilterCondition clueFilterCondition) throws UniqueConstraintsException {
        FilterCondition filterCondition = new FilterCondition();
        filterCondition.setUserId(userId);
        filterCondition.setConditionName(conditionName);
        clueFilterCondition.setIndustryCategorySelct(null);
        filterCondition.setFilterCondition(JSONObject.toJSONString(clueFilterCondition));
        filterCondition.setConditionType(EnterpriseConsts.INFORMATION_TYPE.Clue.value());
        FilterCondition condition = filterConditionRepository.selectFilterConditionByConditionName(userId, conditionName);
        if (condition != null){
            throw new UniqueConstraintsException("名称为：" + conditionName + "的条件组已存在，请勿重复保存");
        }
        filterConditionRepository.insert(filterCondition);
        return filterCondition;
    }

    @Override
    public PageResult viewSavedFilterCondition(Long userId, int page, int size) {
        PageHelper.startPage(page,size);
        List<FilterCondition> filterConditions = filterConditionRepository.viewClueSavedFilterCondition(userId);
        PageInfo<FilterCondition> pageInfo = new PageInfo<>(filterConditions);
        return new PageResult(page, size, (int) pageInfo.getTotal(), filterConditions);
    }

    @Override
    public PageResult selectFilterConditionByKeyName(Long userId, String keyName, int page, int size){
        PageHelper.startPage(page,size);
        List<FilterCondition> filterConditions = filterConditionRepository.selectClueFilterConditionByKeyName(userId, keyName);
        PageInfo<FilterCondition> pageInfo = new PageInfo<>(filterConditions);
        return new PageResult(page, size, (int) pageInfo.getTotal(), filterConditions);
    }

    @Override
    public FilterCondition selectFilterConditionByConditionName(Long userId, String conditionName) {
        return filterConditionRepository.selectFilterConditionByConditionName(userId, conditionName);
    }

    @Override
    public int deleteById(Long id) {
        return filterConditionRepository.deleteById(id);
    }

    @Override
    public List<Enterprise> assign(String idsString, Long responsiblePersonId) throws ArgumentErrorException {
        List<Long> ids = new ArrayList<>();
        if (!StringUtil.isEmpty(idsString)) {
            String[] split = idsString.split(",");
            for (String s : split) {
                ids.add(Long.parseLong(s));
            }
        }
        List<Enterprise> enterpriseList = enterpriseRepository.selectEnterpriseByIdBatch(ids);
        List<Enterprise> updateList = new ArrayList<>();
        for (Enterprise enterprise : enterpriseList){
            if (EnterpriseUtil.canAllocated(enterprise)) {
                enterprise.setAllocationStatus(EnterpriseConsts.ALLOCATION_STATE.Allocated.value());
                SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                enterprise.setAllocationDate(dateformat.format(System.currentTimeMillis()));
                enterprise.setResponsiblePerson(responsiblePersonId);
                updateList.add(enterprise);
            }
        }
        if (!CollectionUtil.isEmpty(updateList)){
            enterpriseRepository.updateBatchById(updateList);

            List<EsDataClueDemand> esDataClueDemands = BeansUtil.listCopy(updateList, EsDataClueDemand.class);
            esDataClueDemandrepository.saveAll(esDataClueDemands);
        }
        return updateList;
    }

    @Override
    public Enterprise selectClueById(Long id) {
        return enterpriseRepository.selectClueById(id);
    }

    @Override
    public FilterCondition selectFilterConditionByConditionId(Long conditionId) {
        return filterConditionRepository.selectFilterConditionById(conditionId);
    }
}